unit Common.Result;

interface

uses System.SysUtils, System.Classes, Common.Json, Common.List, System.Rtti;

type
    TResult = class(TPersistent)
    private
        fCode: Integer;
        fMsg: String;
        fData: String;
    public
        function AsData<T: class, Constructor>(): T;
        function AsDouble(): Double;
        function AsInt: Integer;
        function AsInt64: Int64;
        function AsBoolean: Boolean;
        procedure return;
        class function Obtain(): TResult;
    published
        property Code: Integer read fCode write fCode;
        property Data: String read fData write fData;
        property Msg: String read fMsg write fMsg;
    end;

implementation

{ TResult }

var
    FreedList: TLinkedList;

function TResult.AsBoolean: Boolean;
begin
    Result := Boolean.Parse(fData);
end;

function TResult.AsData<T>: T;
var
    Rtti: TRttiContext;
    rt: TRttiType;
begin
    if TJson.IsObject(fData) then
    begin
        Result := TJson.Deserizlize<T>(fData);
        exit;
    end;
end;

function TResult.AsDouble: Double;
begin
    Result := Double.Parse(fData);
end;

function TResult.AsInt: Integer;
begin
    Result := Integer.Parse(fData);
end;

function TResult.AsInt64: Int64;
begin
    Result := Int64.Parse(fData);
end;

class function TResult.Obtain: TResult;
var
    item: TResult;
begin
    item := FreedList.RemoveFirst;
    if (assigned(item)) then
    begin
        exit(item);
    end;
    Result := TResult.Create;
end;

procedure TResult.return;
begin
    FreedList.Append(self);
end;

procedure Clear;
var
    item: TResult;
begin
    while (not FreedList.IsEmpty) do
    begin
        item := FreedList.RemoveFirst;
        item.Free;
    end;
end;

initialization

FreedList := TLinkedList.Create;

finalization

Clear;
FreedList.Free;

end.
